package cn.ncu.wechat.service.impl;

import cn.ncu.wechat.model.Admin;
import cn.ncu.wechat.model.MiniappConfigDraft;
import cn.ncu.wechat.service.AdminService;
import cn.ncu.wechat.service.MiniappConfigDraftService;
import cn.ncu.wechat.util.Result;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.ncu.wechat.model.MiniappConfig;
import cn.ncu.wechat.dao.MiniappConfigMapper;
import cn.ncu.wechat.service.MiniappConfigService;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import cn.ncu.wechat.util.wechatConfigUtil;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;



/**
* @author 12638
* @description 针对表【miniapp_config(小程序配置表)】的数据库操作Service实现
* @createDate 2025-02-06 21:13:47
*/
@Service
public class MiniappConfigServiceImpl extends ServiceImpl<MiniappConfigMapper, MiniappConfig>
    implements MiniappConfigService{

    @Autowired
    private MiniappConfigMapper miniAppConfigMapper;

    @Autowired
    private MiniappConfigDraftService miniappConfigDraftService;

    @Autowired
    private AdminService adminService;

    @Value("${wx.app.appId}")
    private String appId;

    @Value("${wx.app.appSecret}")
    private String appSecret;

    @Value("${upload.path}")
    private String uploadPath;

    @Value("${cn.ncu.key}")
    private String key;

    @Autowired
    private MiniappConfigMapper miniappConfigMapper;

    @Override
    @Transactional
    public Result<?> publishMiniAppConfig(Map<String, String> request,String authorizationHeader) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(key);
            JWTVerifier jwtVerifier = JWT.require(algorithm).build();
            System.out.println("token="+authorizationHeader);
            DecodedJWT decodedJWT = jwtVerifier.verify(authorizationHeader.substring(7));
            Long id = decodedJWT.getClaim("id").asLong();
            Admin admin = adminService.getById(id);
            if (!request.containsKey("remark")) {
                // 如果没有 remark 属性，返回错误结果
                return Result.error(400,"缺少 remark 属性");
            }
            // 如果有 remark 属性，获取其值
            String remark = request.get("remark");
            MiniappConfigDraft miniappConfigDraft = miniappConfigDraftService.getById(1);
            MiniappConfig miniappConfig = new MiniappConfig();
            miniappConfig.setVersionNumber((float) (miniappConfigDraft.getVersionNumber()+0.1));
            miniappConfigDraft.setVersionNumber((float) (miniappConfigDraft.getVersionNumber()+0.1));
            miniappConfig.setConfigInfo(miniappConfigDraft.getConfigInfo());
            miniappConfig.setPublisher(admin.getUsername());
            miniappConfig.setRemarks(remark);
            miniappConfig.setReleaseDate(new Date(System.currentTimeMillis()));
            boolean succ = save(miniappConfig);
            boolean succ_draft = miniappConfigDraftService.updateById(miniappConfigDraft);
            if (succ && succ_draft) {
                return Result.success(); // 两个都成功，返回成功
            } else {
                throw new RuntimeException("发布异常: 主配置或草稿配置保存失败"); // 抛出异常触发回滚
            }
        } catch (Exception e) {
            return Result.error(500, "发布失败"+e.getMessage());
        }
    }

    @Override
    public Result<?> MIniAppConfigPublishHistory() {
        try {
            List<Map<String, Object>> res = miniappConfigMapper.selectPublishHistory();
            return Result.success(res);
        } catch (Exception e) {
            return Result.error(500, "获取发布历史失败");
        }
    }

    @Override
    public Result<?> MiniAppConfigRollback(Map<String, String> request) {
        try {
            if (!request.containsKey("version")) {
                return Result.error(400, "缺少必要参数或格式不正确");
            }
            Float version_number = Float.parseFloat(request.get("version").toString());
            QueryWrapper<MiniappConfig> queryWrapper = new QueryWrapper<>();
            MiniappConfig exist_version_config = miniappConfigMapper.selectOne(queryWrapper.eq("version_number",version_number));
            if (exist_version_config == null) {
                return Result.error(400,"未找到该版本");
            }
            boolean del = removeById(exist_version_config.getVersionId());
            
            if (del) {
                exist_version_config.setVersionId(null);
                boolean succ = save(exist_version_config);
                if (succ) {
                    return Result.success();
                } else {
                    return Result.error(500, "回滚版本发布失败");
                }
            } else {
                return Result.error(500,"版本回滚失败");
            }
        } catch (Exception e) {
            return Result.error(500, "回滚操作失败");
        }
    }

    @Override
    public Result<?> getMiniAppConfig() {
        try {
            QueryWrapper<MiniappConfig> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("config_info") // 指定查询的列
                    .orderByDesc("version_id")
                    .last("LIMIT 1");

            MiniappConfig config = miniAppConfigMapper.selectOne(queryWrapper);

            if (config != null) {
                String jsonString = config.getConfigInfo().toString();
                // 使用 Gson 将 JSON 字符串转换为 Map
                Gson gson = new Gson();
                Map<String, Object> jsonMap = gson.fromJson(jsonString, Map.class);
                return Result.success(jsonMap);
            } else {
                return Result.error(500, "未查询到当前版本");
            }
        } catch (Exception e) {
            return Result.error(500, "获取当前版本失败：" + e.getMessage());
        }
    }

    @Override
    public Result<?> getQrCode(String path) {
        String accessToken = wechatConfigUtil.getAccessToken(appId, appSecret);
        String apiUrl = "https://api.weixin.qq.com/wxa/getwxacode?access_token=" + accessToken;

        // 请求参数
        String requestBody = "{\"path\": \"" + path + "\", \"width\": 430}";

        try {
            // 创建URL对象
            URL url = new URL(apiUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // 设置请求方法为POST
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);

            // 设置请求头
            connection.setRequestProperty("Content-Type", "application/json; utf-8");
            connection.setRequestProperty("Accept", "application/json");

            // 发送请求
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = requestBody.getBytes("utf-8");
                os.write(input, 0, input.length);
            }

            // 获取响应
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                // 读取响应内容
                InputStream inputStream = connection.getInputStream();
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int bytesRead;

                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    byteArrayOutputStream.write(buffer, 0, bytesRead);
                }

                // 生成唯一文件名
                String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
                String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 8); // 取 UUID 前 8 位
                String fileName = "qrcode_" + timestamp + "_" + uuid + ".png";

                // 创建目录
                File uploadDir = new File(uploadPath);
                if (!uploadDir.exists()) {
                    boolean created = uploadDir.mkdirs();
                    System.out.println("创建上传目录, 结果：" + uploadPath + " " + created);
                }

                // 保存文件
                File destFile = new File(uploadDir, fileName);
                try (FileOutputStream fos = new FileOutputStream(destFile)) {
                    fos.write(byteArrayOutputStream.toByteArray());
                }

                // 构建访问URL
                String file_url = "/upload/" + fileName;

                // 返回结果
                Map<String, Object> data = new HashMap<>();
                data.put("url", file_url);
                return Result.success(data);
            } else {
                return Result.error(responseCode, "获取小程序码失败，响应码: " + responseCode);
            }
        } catch (Exception e) {
            return Result.error(500, "获取小程序码失败：" + e.getMessage());
        }
    }

    @Override
    public Result<?> getVersionNow() {
        try {
            List<Map<String, Object>> config = miniAppConfigMapper.selectLatestConfig();

            if (config != null) {
                return Result.success(config);
            } else {
                return Result.error(500, "未查询到当前版本");
            }
        } catch (Exception e) {
            return Result.error(500, "获取当前版本失败：" + e.getMessage());
        }
    }
}




